using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using Lizk.WebScraper;
using System.Text.RegularExpressions;
using System.Threading;
using HtmlAgilityPack;
using System.Diagnostics;

namespace TVScrapers
{
    public class TVRageScraper : Scraper
    {
        public override ScraperResult[] Search(string search)
        {
            UpdateProgress(new ScraperEventArgs("Connecting to TVRage.com", ScraperEventArgs.ScaperStatus.Connecting));
            List<ScraperResult> results = new List<ScraperResult>();

            string page;
            if (!TryGetPage("http://www.tvrage.com/search.php?search=" + Uri.EscapeUriString(search + "&show_ids=1"), out page))
            {
                UpdateProgress(new ScraperEventArgs("Unable to connect to TVRage.com", ScraperEventArgs.ScaperStatus.Error));
                return new ScraperResult[0];
            }
            UpdateProgress(new ScraperEventArgs("Scraping...", ScraperEventArgs.ScaperStatus.Downloading));

            page = page.Replace("charset=charset", "charset");
            using (StringReader s = new StringReader(page))
            {
                HtmlDocument html = new HtmlDocument();
                html.Load(s);
                //html.LoadHtml(s.ReadToEnd());
                HtmlNodeCollection nc = html.DocumentNode.SelectNodes("//div[starts-with(@id, 'search_begin')]/table/tr/td[@align = 'right']");
                if(nc != null)
                foreach (HtmlNode node in nc)
                {
                    try
                    {
                        HtmlNode anode = node.ParentNode.FirstChild.FirstChild.NextSibling.NextSibling;
                        ScraperResult sr = new ScraperResult(node.InnerText);
                        sr.Title = anode.InnerText;
                        results.Add(sr);
                    }
                    catch (NullReferenceException)
                    {
                        continue;
                    }
                }
                
                /*string line;
                while ((line = s.ReadLine()) != null)
                {
                    if (line.Contains("search_end"))
                    {
                        foreach (string row in line.Split(new string[] { "</tr><tr" }, StringSplitOptions.RemoveEmptyEntries))
                        {
                            if (!row.Contains("[show"))
                                continue;
                            string id = Scrape(0, row, "[show=", "]");
                            ScraperResult sr = new ScraperResult(id);
                            sr.Title = Scrape(0, row, "' >", "</a>");
                            int year;
                            if (Int32.TryParse(Scrape(0, row, "'b2'>", " "), out year))
                                sr.Year = year;
                            results.Add(sr);
                        }
                    }
                }*/
            }
            UpdateProgress(new ScraperEventArgs("Search completed!", ScraperEventArgs.ScaperStatus.Done));
            SearchComplete(results);
            return results.ToArray();
        }
        AutoResetEvent are = new AutoResetEvent(false);
        public override ScraperResult GetTitleInfo(string id)
        {
            UpdateProgress(new ScraperEventArgs("Connecting to TVRage.com", ScraperEventArgs.ScaperStatus.Connecting));

            ScraperResult sr = new ScraperResult(id);
            ThreadPool.QueueUserWorkItem(new WaitCallback(GetEpisodes), sr);

            string page;
            if (!TryGetPage("http://www.tvrage.com/shows/id-" + Uri.EscapeUriString(id), out page))
            {
                UpdateProgress(new ScraperEventArgs("Unable to connect to TVRage.com", ScraperEventArgs.ScaperStatus.Error));
                return null;
            }
            UpdateProgress(new ScraperEventArgs("Scraping...", ScraperEventArgs.ScaperStatus.Downloading));


            using (StringReader s = new StringReader(page))
            {
                string line;
                while ((line = s.ReadLine()) != null)
                {
                    if (line.Contains("\" Summary"))
                    {
                        sr.Title = Scrape(0, line, "\"", "\" Summary");
                        while (!line.Contains("<td>"))
                            line = s.ReadLine();


                        if (line.Contains("src=\""))
                        {
                            sr.ImageUrl = Scrape(0, line, "src=\"", "\" border=");
                            line = s.ReadLine();
                        }
                        string summary = "";
                        while (!line.Contains("</td></tr><tr>"))
                        {
                            summary += line;
                            line = s.ReadLine();
                        }
                        sr.Summary = ClearHTML(br2nl(Regex.Replace(summary, @"\s+", @" ").Trim()));
                    }
                    if (line.Contains("Genre: "))
                    {
                        foreach (string genre in Scrape(0, line, "<td>", "</td>").Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries))
                        {
                            sr.Genres.Add(genre.Trim());
                        }
                        
                    }

                    if (line.Contains("Premiere: "))
                    {
                        DateTime premiere;
                        if (DateTime.TryParse(Scrape(0, line, "<td>", "</td>"), out premiere))
                            sr.Year = premiere.Year;

                    }
                }
            }
            UpdateProgress(new ScraperEventArgs("Scrape completed!", ScraperEventArgs.ScaperStatus.Done));
            are.WaitOne();
            ScrapeComplete(sr);
            return sr;
        }
        Regex episodeRX = new Regex(@"\d+\s*:(\d+)x(\d+)\s*-\s*([^<]+)");
        public void GetEpisodes(object o)
        {
            ScraperResult sr = (ScraperResult)o;
            string page;
            if (!TryGetPage("http://www.tvrage.com/shows/id-" + Uri.EscapeUriString(sr.ID) + "/episode_guide/all", out page))
            {
                are.Set();
                return;
            }


            using (StringReader s = new StringReader(page))
            {
                string line;
                while ((line = s.ReadLine()) != null)
                {
                    int index = line.IndexOf("='wlink' href='");
                    if (index > -1)
                    {
                        int ie;
                        string episode = Scrape(index, line, "'>", "</a>", out ie);
                        Match m = episodeRX.Match(episode);
                        if (m.Success)
                        {
                            string date = Scrape(ie, line, "(", ")");
                            Episode ep = new Episode(m.Groups[3].Value);
                            DateTime air;
                            if (DateTime.TryParse(date, out air))
                            {
                                ep.AirDate = air;
                            }
                            int season, e;
                            if(Int32.TryParse(m.Groups[1].Value, out season))
                                ep.Season = season;
                            if(Int32.TryParse(m.Groups[2].Value, out e))
                                ep.EpisodeNumber = e;

                            while (!line.Contains("</font>"))
                                line += s.ReadLine();

                            ep.Summary = ClearHTML(br2nl(Scrape(0, line, "'black'>", "</font>")));
                            sr.Episodes.Add(ep);
                        }
                        

                    }
                    
                }
            }
            are.Set();
        }




    }
}
